package com.desginer.create.protype;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * https://time.geekbang.org/column/article/200786
 *
 * 原型模式
 * 浅拷贝：指拷贝索引，不复制对象
 * 深拷贝，递归遍历重新生成对象内存地址
 *
 * 选择策略​​
 * ​​优先浅拷贝​​：当对象无嵌套引用或需共享数据时（性能最优）。
 * ​​必须深拷贝​​：嵌套对象需完全独立、并发编程或持久化场景。
 * ​​原型模式搭配​​：若需高频克隆复杂对象，用原型模式+深拷贝组合（如游戏实体生成
 *
 */
public class ProtypeTest {

    public static void main(String[] args) {

        //假设是从数据库查询10万条数据
        HashMap<String, Integer> db = new HashMap<String, Integer>();

        // 浅拷贝  只复制对象
        HashMap<String, Integer> clones = (HashMap<String, Integer>) db.clone();

        // 深拷贝  递归遍历重新生成
        db.entrySet().forEach(entry -> {
            clones.put(entry.getKey(), entry.getValue());
            if (db.containsKey(entry.getKey())) {
                clones.remove(entry.getKey());
            }

            clones.put(entry.getKey(), entry.getValue());
        });

    }

    /**
     * 深拷贝，序列化和反序列化
     *
     * @param object
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public Object deepCopy(Object object) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(object);

        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);

        return oi.readObject();
    }
}
